import utime, gc
from machine import RTC
import usocket as socket
import ustruct as struct

# NTP_DELTA 是 NTP 时间与 Unix 时间戳之间的差值（以秒为单位）
# NTP_DELTA (date(2000, 1, 1) - date(1900, 1, 1)).days * 24*60*60
NTP_DELTA = 3155673600


def time(host="pool.ntp.org", utc=28800):
    """
    从 NTP 服务器获取当前时间并转换为 UTC 时间元组。
    
    参数:
        host: NTP 服务器的域名，默认为 "pool.ntp.org"。
        utc: UTC 时间的偏移量，默认为 28800 秒，即 UTC+8。
        
    返回:
        返回一个表示 UTC 时间的时间元组。
    """
    NTP_QUERY = bytearray(48)
    NTP_QUERY[0] = 0x1B
    addr = socket.getaddrinfo(host, 123)[0][-1]
    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    try:
        s.settimeout(1)
        res = s.sendto(NTP_QUERY, addr)
        msg = s.recv(48)
    finally:
        del addr
        s.close()
    gc.collect()
    val = struct.unpack("!I", msg[40:44])[0]
    return utime.gmtime(val - NTP_DELTA + utc)


# 当前 MicroPython 中没有时区支持，RTC 时间设置为 UTC 时间。
def settime(times):
    """
    设置 MicroPython 开发板的 RTC 时间。
    
    参数:
        times: 包含时间信息的字符串或元组，至少应包括年、月、日、时、分和秒。
    """
    if isinstance(times, str):
        try:
            val = eval(times)
            if len(val) >= 6:
                times = (val[0], val[1], val[2], 0, val[3], val[4], val[5], 0)
            else:
                raise ValueError("时钟信息格式错误")
        except:
            raise ValueError("时钟信息格式错误，使用 ',' 分隔至少 6 个数值")
    if isinstance(times, tuple):
        if 6 <= len(times) <= 8:
            RTC().datetime((times[0], times[1], times[2], 0, times[3], times[4], times[5], 0))
        else:
            raise ValueError("settime 需要一个长度为 6~8 的元组")
